#pragma once

#include "Sock.hpp"
#include "Protocol.hpp"

#include <iostream>
#include <string>
#include <functional>
#include <pthread.h>

namespace CalcServer
{
    using func_t = std::function<void(my_protocol::Request&, my_protocol::Response*)>;
    class TcpServer;

    // 线程所需要的信息类
    class ThreadDate
    {
    public:
        ThreadDate(int& sock, std::string& ip, uint16_t& port, TcpServer* ptsvr)
            :_sock(sock), _ip(ip), _port(port), _ptsvr(ptsvr)
        {}

        ~ThreadDate()
        {}

        int _sock;
        std::string _ip;
        uint16_t _port;
        TcpServer* _ptsvr; // 回指指针
    };

    class TcpServer
    {
        const static uint16_t default_port = 8888;

    private:
        // 线程的执行函数
        static void* threadRoutine(void* args)
        {
            // 线程剥离
            pthread_detach(pthread_self());

            ThreadDate* td = static_cast<ThreadDate*>(args);
            td->_ptsvr->ServiceIO(td->_sock, td->_ip, td->_port);
            delete td;
            return nullptr;
        }

        // 进行IO服务的函数
        void ServiceIO(const int& sock, const std::string ip, const uint16_t& port)
        {
            std::string inBuff;
            while(true)
            {
                // 1.读取数据
                std::string package; // 假设这是已经读取到的数据包，格式为 "5\r\n1 + 1"
                int len = my_protocol::ReadPackage(sock, inBuff, &package);
                if(len < 0)
                    break;
                else if(len == 0)
                {
                    std::cout << "已经读取到了: " << inBuff  << " 其他部分还在读取中" << std::endl;
                    continue;
                }

                // 2.移除报头
                my_protocol::RemoveHeader(package, len);

                // 3.反序列化
                my_protocol::Request req;
                if(req.Deserialization(package) == false)
                {
                    logMessage(Warning, "Deserialization fail!");
                    continue;
                }

                // 4.业务处理
                my_protocol::Response resp; // 业务处理完成后得到的响应对象
                _func(req, &resp);

                // 5.序列化
                std::string sendMsg;
                resp.Serialization(&sendMsg);

                // 6.添加报头
                my_protocol::AddHeader(sendMsg);

                std::cout << "添加报头完成: " << sendMsg << std::endl << std::endl;

                // 7.发送数据
                send(sock, sendMsg.c_str(), sendMsg.size(), 0);
            }
        }

    public:
        TcpServer(const func_t& func, const uint16_t port = default_port)
            :_func(func), _port(port)
        {}

        // 初始化服务器
        void Init()
        {
            _listen_sock.Socket();
            _listen_sock.Bind(_port);
            _listen_sock.Listen();
        }


        // 启动服务器
        void Start()
        {
            while(true)
            {
                std::string ip;
                uint16_t port;

                int sock = _listen_sock.Accept(&ip, &port);
                if(sock == -1)
                    continue;
                
                // 创建子线程，执行业务处理
                pthread_t tid;
                ThreadDate* td = new ThreadDate(sock, ip, port, this);
                pthread_create(&tid, nullptr, threadRoutine, td);
            }
        }

        ~TcpServer()
        {
            _listen_sock.Close();
        }

    private:
        Sock _listen_sock; // 监听套接字
        uint16_t _port;    // 服务器端口号
        func_t _func;      // 上层传入的业务处理函数
    };
}